package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.expression;

import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.alibaba.fastjson.JSON;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Set;
import java.util.HashSet;

import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
import static java.util.Collections.emptySet;

/**
 * 改进版：分配给发起人的 Leader 审批的 Expression 流程表达式
 * 1. 当本级部门无负责人时，自动向上查找
 * 2. 当负责人是自己时，自动跳过并向上查找
 * 3. 添加最大层级限制防止无限递归
 */
@Component
public class BpmTaskAssignLeaderExpression {

    private static final int MAX_LEVEL = 10; // 最大向上查找层级

    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private DeptApi deptApi;
    @Resource
    private BpmProcessInstanceService processInstanceService;

    /**
     * 计算审批的候选人
     *
     * @param execution 流程执行实体
     * @param level 指定级别（从1开始）
     * @return 符合条件的领导集合
     */
    public Set<Long> calculateUsers(DelegateExecution execution, int level) {
        System.out.println("配给发起人的 Leader 审批.calculateUsers");
        Assert.isTrue(level > 0, "level 必须大于 0");
        // 1. 获取流程发起人
        ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
        Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
        AdminUserRespDTO startUser = adminUserApi.getUser(startUserId);
        System.out.println("1. 获取流程发起人");
        // 2. 获取初始部门
        DeptRespDTO currentDept = getStartUserDept(startUser);
        if (currentDept == null) {
            return emptySet();
        }
        System.out.println("2. 获取初始部门");
        // 3. 向上查找符合条件的负责人
        Set<Long> leaderUserIds = new HashSet<>();
        int currentLevel = 1;

        while (currentDept != null && currentLevel <= MAX_LEVEL) {
            // 3.1 检查是否达到目标层级
            if (currentLevel >= level) {
                // 3.2 检查当前部门是否有有效负责人（非自己且状态正常）
                if (isValidLeader(currentDept, startUserId)) {
                    leaderUserIds.add(currentDept.getLeaderUserId());
                    break;
                }
            }
            System.out.println("3.1 检查是否达到目标层级");
            // 3.3 继续向上查找
            currentDept = currentDept.getParentId() != null ?
                    deptApi.getDept(currentDept.getParentId()) : null;
            currentLevel++;
            System.out.println("3.3 继续向上查找");
        }
        System.out.println("结束");
        return leaderUserIds.isEmpty() ? emptySet() : leaderUserIds;
    }

    /**
     * 获取发起人所在部门
     */
    private DeptRespDTO getStartUserDept(AdminUserRespDTO startUser) {
        if (startUser.getDeptId() == null) {
            return null;
        }
        return deptApi.getDept(startUser.getDeptId());
    }

    /**
     * 判断是否为有效负责人
     * 1. 部门有负责人
     * 2. 负责人不是自己
     * 3. 负责人账号状态正常（可选，根据业务需求）
     */
    private boolean isValidLeader(DeptRespDTO dept, Long startUserId) {
        if (dept.getLeaderUserId() == null) {
            return false;
        }

        // 检查负责人是否是自己
        if (dept.getLeaderUserId().equals(startUserId)) {
            return false;
        }

        // 可选：检查负责人账号状态
        AdminUserRespDTO leader = adminUserApi.getUser(dept.getLeaderUserId());
        return leader != null && leader.getStatus() == 0; // 假设0表示正常状态
    }
}
